package com.gitee.fsmxm.thinking.in.spring.dependency.lookup;

import com.gitee.fsmxm.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

/**
 * 安全 依赖查找 demo
 */
public class SafetyDependencyLookupDemo {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();

        applicationContext.register(SafetyDependencyLookupDemo.class);


        applicationContext.refresh();

        // 演示 BeanFactory#getBean 的安全性
        displayBeanFactoryGetBean(applicationContext);
        // 演示 ObjectProvider#getObject 的安全性
        displayObjectProviderGetObject(applicationContext);
        // 演示 ObjectProvider#getIfAvailable 的安全性
        displayObjectProviderGetIfAvailable(applicationContext);
        // 演示 ListableBeanFactory#getBeansOfType 的安全性
        displayBeanFactoryGetBeansOfType(applicationContext);
        // 演示 ObjectProvider#stream 的安全性
        displayObjectProviderStreamForEach(applicationContext);

        applicationContext.close();

    }

    private static void displayObjectProviderStreamForEach(BeanFactory beanFactory) {
        ObjectProvider<User> beanProvider = beanFactory.getBeanProvider(User.class);
        try {
            beanProvider.stream().forEach(System.out::println);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    private static void displayBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {
        try {
            Map<String, User> beansOfType = beanFactory.getBeansOfType(User.class);
            System.out.println(beansOfType);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    private static void displayObjectProviderGetIfAvailable(BeanFactory beanFactory) {
        ObjectProvider<User> beanProvider = beanFactory.getBeanProvider(User.class);
        try {
            User ifAvailable = beanProvider.getIfAvailable();
            System.out.println(ifAvailable);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    private static void displayObjectProviderGetObject(BeanFactory beanFactory) {
        ObjectProvider<User> beanProvider = beanFactory.getBeanProvider(User.class);
        try {
            User object = beanProvider.getObject();
            System.out.println(object);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

    private static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
        try {
            User bean = beanFactory.getBean(User.class);
            System.out.println(bean);
        } catch (BeansException e) {
            e.printStackTrace();
        }
    }

}
